home *** CD-ROM | disk | FTP | other *** search
- *
- *
- * phaser.asm
- *
- *
-
- *
- * Knobs - adjust these values within suggested range for
- * variations on the effect.
- *
- * Patch Name Dry Wet FB Top Bottom Speed
- * Basic phase 07fffh 07fffh 00000h 0f000h 07ff0h 0008h
- * Phase w/ FB 07fffh 07fffh 05000h 0f000h 07800h 0006h
- * Med. phase 07fffh 07fffh 00000h 0f000h 07800h 0020h
- * Fast phase 07fffh 07fffh 00000h 00000h 07000h 0050h
- * Invert w/ invert FB 07fffh 08000h 0a000h 0f000h 07400h 0002h
- *
- DRY_LEVEL .set 07fffh ; (0 - 07fffh dry signal level)
- WET_LEVEL .set 07fffh ; (08000h - 7fffh wet signal level)
- FB_LEVEL .set 01000h ; (08000h - 7fffh regeneration amount)
- SWEEP_TOP .set 0f000h ; top end of sweep range (0f000 - 0800h)
- SWEEP_BOT .set 07800h ; bottom end of sweep range (07ff0h - 0900h)
- SWEEP_SPEED .set 00012h ; rate of sweep (01h - 080h)
-
- *
- * Data storage
- *
- SPEED .set 00h ; storage for SWEEP_SPEED param
- WET .set 01h ; storage for WET_LEVEL
- DRY .set 02h ; storage for DRY_LEVEL
- FEEDBACK .set 03h ; storage for FB_LEVEL
- COEF_HI .set 04h ; coefficient of filter
- COEF_LO .set 05h ; fractional part of coefficient
- LX1 .set 06h ; filter states
- LY1 .set 07h ; .
- LX2 .set 08h ; .
- LY2 .set 09h ; .
- LX3 .set 0ah ; .
- LY3 .set 0bh ; .
- LX4 .set 0ch ; .
- LY4 .set 0dh ; .
- TMP .set 0eh ; temp register
- INPUT .set 0fh ; dry input
- OUTPUT .set 10h ; output of filter chain
- IOREG .set 11h ; filter in/out reg
- INC_LO .set 12h ; coefficient inc/dec value LSW
- INC_HI .set 13h ; ditto but MSW
- SWEEPDIR .set 14h ; track direction of sweep
- LOOKUP .set 15h ; lookup table index
-
- .include "setup.asm"
-
- *
- * main
- *
- main:
- ssxm ; set sign extension mode
- spm 1 ; set P shift for Q15 (1 bit left shift
- ; from P => accum)
- sovm ; set clipping overflow mode for
- ; "analog" processing
- ldpk 8 ; data at 0x400
-
- lalk SWEEP_SPEED ; sweep rate
- sacl SPEED
- lalk FB_LEVEL
- sacl FEEDBACK ; delayed signal feedback mix
- lalk WET_LEVEL
- sacl WET ; delayed signal output mix
- lalk DRY_LEVEL
- sacl DRY ; straight signal output mix
- lalk 01000h ; midrange value
- sacl COEF_HI
- lack 0
- sacl INC_LO
- sacl INC_HI
- sacl SWEEPDIR ; initially down in frequency
- lack 014h ; enable AIC recv interrupts
- ldpk 0
- sacl IMR
- ldpk 8
-
- ; loop here forever processing interrupts
- loop: idle
- b loop
-
- ; table of sweep adjustment factors
- SWEEPTAB:
- .word 11970
- .word 11600
- .word 10890
- .word 9700
- .word 8200
- .word 6300
- .word 3950
- .word 1000
- .word 1000
- .word 1000
- .word 1000
- .word 1000
- .word 1000
- .word 1000
- .word 1000
- .word 12330
-
- *
- * rint
- *
- * Recv interrupt handler performs all the work. Since there is
- * no main thread, there is no need to save or restore regs.
- *
- * Difference equation is:
- *
- * Y = COEF * (X + LY) - LX
- *
- * Where:
- * X = input value
- * Y = output
- * LX = last input
- * LY = last output
- *
- rint:
- ; note: no need to save/restore processor state since
- ; main thread does absolutely nothing
- sovm
-
- ; read in and store new input value
- ldpk 0
- lac DRR
- ldpk 8
- sfr ; dump lowest 2 junk bits
- sfr
- sacl IOREG
- sacl INPUT ; keep copy of dry input
-
- ; do feedback before entering filters
- lt OUTPUT ; get last output value
- mpy FEEDBACK
- pac
- addh INPUT ; filter input value is ready
- sach IOREG ; pass to filter both in IOREG and accum
-
- ; do first filter section
- addh LY1 ; add last Y
- sach TMP
- lt COEF_HI ; scale sum by COEF
- mpy TMP
- pac ; move to accum
- subh LX1 ; subtract last X
- sach LY1 ; output Y is ready, save in LY
- lar AR1,IOREG ; save X in LX
- sar AR1,LX1
- sach IOREG ; pass to next filter
-
- ; do first second section
- addh LY2 ; add last Y
- sach TMP
- lt COEF_HI ; scale sum by COEF
- mpy TMP
- pac ; move to accum
- subh LX2 ; subtract last X
- sach LY2 ; output Y is ready, save in LY
- lar AR1,IOREG ; save X in LX
- sar AR1,LX2
- sach IOREG ; pass to next filter
-
- ; do third filter section
- addh LY3 ; add last Y
- sach TMP
- lt COEF_HI ; scale sum by COEF
- mpy TMP
- pac ; move to accum
- subh LX3 ; subtract last X
- sach LY3 ; output Y is ready, save in LY
- lar AR1,IOREG ; save X in LX
- sar AR1,LX3
- sach IOREG ; pass to next filter
-
- ; do fourth filter section
- addh LY4 ; add last Y
- sach TMP
- lt COEF_HI ; scale sum by COEF
- mpy TMP
- pac ; move to accum
- subh LX4 ; subtract last X
- sach LY4 ; output Y is ready, save in LY
- lar AR1,IOREG ; save X in LX
- sar AR1,LX4
- sach IOREG ; pass to next filter
- sach OUTPUT ; save filter chain's output value
-
- ; do level scaling on direct and wet
- lt OUTPUT
- mpy WET ; scale wet signal
- pac
- lt INPUT ; get original input value
- mpy DRY ; scale dry signal
- apac ; generate composite final output
- sach TMP
- lac TMP ; prepare final output for AIC
- andk 0fffch ; clear lowest 2 bits
- ldpk 0
- sacl DXR ; do output
- ldpk 8
-
- ; adjust the coefficient
- rovm ; normal arithmetic
- lac COEF_LO ; 32 bit add
- add INC_LO
- sacl COEF_LO
- sovm
- lac COEF_HI
- addc INC_HI
- sacl COEF_HI
- rovm
- ; see if we hit the upper or lower bounds of the sweep
- lac SWEEPDIR
- bz down
- lalk SWEEP_TOP
- sub COEF_HI
- blez adj_inc
- lack 0 ; gonna start going down in freq
- sacl SWEEPDIR
- b reverse
- down:
- lalk SWEEP_BOT
- sub COEF_HI
- bgz adj_inc
- lack 1 ; gonna start going up in freq
- sacl SWEEPDIR
- reverse:
- lac SPEED ; reverse the sweep
- neg ; by swapping sign of speed value
- sacl SPEED
- adj_inc:
- ; adjust the increment value based on region of sweep
- rsxm
- lac COEF_HI,4 ; get high nibble into accum high 0-3
- sach LOOKUP
- ssxm
- lalk SWEEPTAB
- add LOOKUP
- tblr TMP ; read the value from table into TMP
- lt TMP ; multiply adjustment factor
- mpy SPEED ; by sweep
- pac
- sacl INC_LO ; new 32 bit increment value
- sach INC_HI
- done:
- eint
- ret
-
-
- *
- * tint
- *
- * Timer interrupt - not used.
- *
- tint:
- eint
- ret
-
- *
- * xint
- *
- * AIC xmit interrupt - not used.
- *
- xint:
- eint
- ret
-